package nl.Viewer.ViewManager;

import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import nl.Viewer.Application;
import nl.Viewer.SerializedObjects.Modality;
import nl.Viewer.SerializedObjects.Visualization;
import nl.Viewer.Sessions.ClientSideSession;
import nl.Viewer.ViewManager.Controllers.GenericController;
import nl.Viewer.ViewManager.Objects.OutputVisualizationTuple;

/**
 * This class manages a single frame within the viewDesktop. Some required frame events are handled and re-directed to
 * the ViewManager.
 * 
 * @author Jeroen Verschuur
 * 
 */

public class ViewFrame extends JInternalFrame implements InternalFrameListener, ComponentListener {
   private static final long         serialVersionUID = -1;
   protected final ViewDesktop       parent;
   protected final GenericController visualizationController;
   private String                    defaultTitle;

   public ViewFrame( Visualization visualization, Modality modality, ClientSideSession session,
         OutputVisualizationTuple tuple, ViewDesktop parent ) throws Exception {

      super( modality.getName() + " - " + visualization.getName(), true, // resizable
            true, // closable
            true, // maximizable
            true );// iconifiable

      this.defaultTitle = modality.getName() + " - " + visualization.getName();
      this.parent = parent;

      this.addInternalFrameListener( this );
      this.addComponentListener( this );

      this.visualizationController = GenericController.newInstance( tuple, visualization, modality, session );

      // fetch the parameter list from the server
      if( this.visualizationController == null ) {
         System.out.println( "Warning: default view selected (no render panel)" );
         this.setContentPane( new JPanel() );
      } else {
         this.setContentPane( visualizationController );
      }
      // actually create the panel
      this.pack();
   }

   public void componentMoved( ComponentEvent e ) {
   }

   public void componentShown( ComponentEvent e ) {
   }

   public void componentHidden( ComponentEvent e ) {
   }

   public void componentResized( ComponentEvent e ) {
      // System.out.println("Resized");
      if( this.isMaximum() ) {
         // System.out.println("maximized");
      }
   }

   /**
    * This overrides the JInternalFrame.setTitle, to prepend the defaultTitle to the frame title
    * 
    */

   public void setTitle( String title ) {
      super.setTitle( defaultTitle + " - " + title );
   }

   public void internalFrameActivated( InternalFrameEvent e ) {
      // set the orientation and parameter panels for the selected view
      ViewFrame frame = (ViewFrame)e.getInternalFrame();

      if( frame != null ) {
         Application.viewManager.setOrientationAndParameterTabs( frame.visualizationController );
      }
   }

   public void internalFrameDeactivated( InternalFrameEvent e ) {
      // remove the orientation and parameters panels
      Application.viewManager.setOrientationAndParameterTabs( null );
   }

   public void internalFrameIconified( InternalFrameEvent e ) {
      // remove the orientation and parameters panels
      Application.viewManager.setOrientationAndParameterTabs( null );
   }

   public void internalFrameDeiconified( InternalFrameEvent e ) {
      // set the orientation and parameter panels for the selected view
      ViewFrame frame = (ViewFrame)e.getInternalFrame();

      if( frame != null ) {
         Application.viewManager.setOrientationAndParameterTabs( frame.visualizationController );
      }
   }

   public void internalFrameOpened( InternalFrameEvent e ) {
   }

   public void internalFrameClosed( InternalFrameEvent e ) {
      System.gc();
      System.out.println( "Post-internalFrameClosed session in use memory: " + ( Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() ) );

   }

   public void internalFrameClosing( InternalFrameEvent e ) {
      // disconnect the session
      Application.viewManager.closeSessionForView( this.visualizationController );

      if( visualizationController != null ) {
         visualizationController.shutdown();
      }
      System.gc();
      System.out.println( "Post-internalFrameClosing session in use memory: " + ( Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() ) );
   }

   public GenericController getView() {
      return visualizationController;
   }
}
